package edu.hawaii.ics414.blackjack.practiceMode;

import edu.hawaii.ics414.blackjack.card.*;
import edu.hawaii.ics414.blackjack.player.*;

import java.util.Scanner;

/**
 * Practice Mode for the BlackJack Game.
 * 
 * @author Wei Wang
 *
 */
public class PracticeMode
{

  /**
   * Creates a Player with 2000 game cash.
   */
  private Dealer Dealer;
  private Player Player;
  
  /**
   * Variables
   */
  public Scanner s;
  private int NumChoice;
  private int Bet;
  private String Choice;
  private int RoundCounter;
  private String spacer;
  
  /**
   * PracticeMode Constructor
   */
  public PracticeMode()
  {
    Dealer = new Dealer(0);
    Player = new Player(2000);
    s = new Scanner(System.in);
    NumChoice = 0;
    Bet = 0;
    Choice = "";
    RoundCounter = 1;
  }
  
  /**
   * The game itself
   */
  public void GameStart()
  {
    /**
     * Creating a GameDeck with 6 decks.
     */
    GameDeck GameDeck = new GameDeck(6);
    
    /**
     * The greeting message upon the player chooses to play the Practice Mode.
     */
    System.out.println("Welcome to the Practice Mode!");
    System.out.println("The practice mode uses 6 decks.");
    System.out.println("Dealer hits on soft 17.");
    System.out.println("You begin with $2000");
    System.out.println("Game Start!");
    System.out.print("     Enter anything to continue.");
    spacer = s.nextLine();
    System.out.println("");

    //Checks for the amount of game cash the Player has, 
    //if less than 10, then the player has ran out of cash
    while(Player.getMoney() >= 10 && !Choice.equals("q"))
    {
      
      //Checks if the Player chooses to quit.
      while(!Choice.equals("q"))
      {
        
        //Shuffles and uses a new deck if there are less than 105 cards left in the deck.
        if(GameDeck.getSize() > 105)
        {
          System.out.println("*************************************************");
          System.out.println("Hand: " + RoundCounter);
          System.out.println("You have: $" + Player.getMoney());
          
            //If the Player has less than the maximum bet of 100, display Player's money as max bet.
            if(Player.getMoney() < 100)
            {
              System.out.println("You can bet up to $" + (Player.getMoney() - (Player.getMoney() % 10)));
            }
            else
            {
              System.out.println("You can bet up to $100.");
            }
            
            //Asks for the bet
            System.out.print("Your Bet (or enter q to quit): ");
            System.out.println("");
            Choice = s.nextLine();
            if(!Choice.equalsIgnoreCase("Q") || !Choice.equals("q"))
            {
              try
              {
                Bet = Integer.parseInt(Choice);
                
                //The bet must be less than 100, and greater than 0
                if(Bet <= 100 && Bet > 9 && Bet % 10 ==0)
                {
                  
                  //The bet must also be more than what the Player has
                  if(Player.canBet(Bet))
                  {
                    //Sets the bet
                    Player.setBet(0, Bet);
                    
                    
                    //Deal the cards
                    Dealer.play(GameDeck, 1 - 1, Action.HIT);
                    Dealer.play(GameDeck, 1 - 1, Action.HIT);
                    Player.play(GameDeck, 1 - 1, Action.HIT);
                    Player.play(GameDeck, 1 - 1, Action.HIT);
                    
                    
                    
                    //Displays the hands.
                    DisplayHands(Dealer, Player);
                    
                    //splitting of the hands
                    split(GameDeck, Dealer, Player);
                    
                    //loop through hands that the player has
                    for(int i = 1; i < 5; i++)
                    {
                      if(Player.hands[i - 1][0] != null) 
                      {
                        PlayerTurn(GameDeck, Player, i);
                      }
                    }
                    System.out.print("     Enter anything to continue.");
                    spacer = s.nextLine();
                    System.out.println("");
                    System.out.println("----------------Dealer's-Turn----------------");
                    System.out.println("");
                    
                    //Dealer's turn
                    boolean dealerTurn = false;
                    for(int i = 1; i < 5; i++) 
                    {
                      if(Player.hands[i - 1][0] != null && !Player.handValue(i - 1).equals("BUSTED")){
                        dealerTurn = true;
                      }
                    }
                    if(Player.handValue(0).equals("BLACKJACK")) {
                      dealerTurn = false;
                    }
                    if(dealerTurn) 
                    {
                      DealerTurn(Dealer, GameDeck);
                    }
                    if(!dealerTurn && !Player.handValue(0).equals("BLACKJACK"))
                    {
                      System.out.println("All of your hands BUSTED");
                    } 
                    else if(Player.handValue(0).equals("BLACKJACK") && !dealerTurn)
                    {
                      System.out.println("Your hand is a BLACKJACK");
                    }
                    System.out.println("");
                    System.out.println("-------------------Payout--------------------");
                    System.out.println("");
                    
                    //Payout
                    Payout(Dealer, Player);
                    System.out.println("");
                    
                    //RoundEnd
                    ClearTable(Dealer, Player);
                    RoundCounter++;
                  }
                  
                  //Error message displayed when the player bets more than what he has
                  else
                  {
                    System.out.println("You do not have enough money to make this bet!");
                  }
                }
                
                //Error message displayed when the Player bets more than the maximum bet allowed
                else
                {
                  if(Bet > 100)
                  {
                    System.out.println("You cannot bet more than $100");
                  }
                  else if (Bet % 10 != 0)
                  {
                    System.out.println("You can only bet multiples of 10");
                  }
                  else
                  {
                    System.out.println("You cannot bet less than $10");
                  }
                }
              }
              catch (NumberFormatException NFE)
              {
                System.out.println("Your bet was invalid.");
              }
            }

        }
        
        //Gets and Shuffles a new Deck when there are not enough cards in the deck
        else
        {
          GameDeck = new GameDeck(6);
        }
      }
      
      //GameOver Message, Displayed when the Player chooses to quit.
      System.out.println("You have chosen to quit the game, you have $" + Player.getMoney() + " left.");
      if(Player.getMoney() > 2000){
        System.out.println("You have won $" + (Player.getMoney() - 2000) + ".");
      }
      else if(Player.getMoney() < 2000)
      {
        System.out.println("You have lost $" + (2000 - Player.getMoney()) + ".");
      }
      else
      {
        System.out.println("You managed to break even.");
      }
    }
    
    //GameOver Message, Displayed when the game ends with the player has no money left.
    if(Player.getMoney() < 10)
    {
      System.out.println("You have lost all of your money.");
      System.out.println("GAME OVER");
    }
    System.out.println("Thank you for playing the practice mode, please look forward to the full release!");
  }
  
  public void DisplayHands(Dealer Dealer, Player Player)
  {
    System.out.println("-------------------Dealing------------------");
    System.out.println("");
    System.out.println("You have bet $" + Player.getBet(0) + ".");
    System.out.println("Dealer hand: ");
    System.out.print(Dealer.getCards());
    System.out.println("Your hands: ");
    System.out.println(Player.getCards());
    System.out.println("------------------Your-Turn------------------");
  }
  
  /**
   * The split part of is the first thing happens after dealing.
   * In order to be a successful split, Player must have a hand of two cards with same values,
   * as well as having enough money to make the same amount of bets as the initial bet.
   * A previously Split hand cannot be split again.
   * A player can split a maximum of three times, leaving the Player with a maximum of four hands.
   * @param GameDeck
   * @param Dealer
   * @param Player
   */
  public void split(GameDeck GameDeck,Dealer Dealer, Player Player)
  {
    Scanner s2 = new Scanner(System.in);
    int InitialBet = Player.getBet(0);
    Choice = "";
    //Checks if the player can split the first hand.
    if(Player.canSplit(1 - 1))
    {
      System.out.println("Would you like to split your first hand? Y/N: ");
      Choice = s2.nextLine();
      while(!Choice.equalsIgnoreCase("Q"))
      {
        if(Choice.equalsIgnoreCase("Y"))
        {
          
          //If the player does not have enough money to place down,
          //then the player cannot split.
          if(Player.canBet(InitialBet))
          {
            Player.play(GameDeck, 1 - 1, Action.SPLIT);
            System.out.println("You splitted your first hand.");
            System.out.println(Player.getCards());
            Player.setBet(2 - 1, InitialBet);
          }
          //displayDealerCovered(Dealer, Player);
            
          //Checks if the player can split the new hand (second hand).
          if(Player.canSplit(2 - 1))
          {
            System.out.println("Would you like to split your second hand? Y/N");
            while(!Choice.equalsIgnoreCase("Q"))
            {
              Choice = s2.nextLine();
              if(Choice.equalsIgnoreCase("Y"))
              {
                //If the player does not have enough money to place down,
                //then the player cannot split.
                if(Player.canBet(InitialBet))
                {
                  Player.play(GameDeck, 2 - 1, Action.SPLIT);
                  System.out.println("You splitted your second hand.");
                  System.out.println(Player.getCards());
                  Player.setBet(3 - 1, InitialBet);
                }
                //displayDealerCovered(Dealer, Player);
                 
                //Checks if the player can split the new hand (third hand).
                if(Player.canSplit(3 - 1))
                {
                  System.out.println("Would you like to split your third hand? Y/N");
                  while(!Choice.equalsIgnoreCase("Q"))
                  {
                    Choice = s2.nextLine();
                    if(Choice.equalsIgnoreCase("Y"))
                    {
                      //If the player does not have enough money to place down,
                      //then the player cannot split.
                      if(Player.canBet(InitialBet))
                      {
                        Player.play(GameDeck, 3 - 1, Action.SPLIT);
                        System.out.println("You splitted your third hand.");
                        System.out.println(Player.getCards());
                        Player.setBet(4 - 1, InitialBet);
                      }
                      Choice = "Q";
                      //displayDealerCovered(Dealer, Player);
                    }
                    else if(Choice.equalsIgnoreCase("N"))
                    {
                      System.out.println("You have not split your third hand.");
                      Choice = "Q";
                      //displayDealerCovered(Dealer, Player);
                    }
                    else
                    {
                      System.out.println("Invalid Option!");
                      Choice = "";
                      Choice = s2.nextLine();
                      //displayDealerCovered(Dealer, Player);
                    }
                  }
                }
                Choice = "Q";
              }
              else if(Choice.equalsIgnoreCase("N"))
              {
                System.out.println("You have not split your second hand.");
                Choice = "Q";
                //displayDealerCovered(Dealer, Player);
              }
              else
              {
                System.out.println("Invalid Option!");
                Choice = "";
                Choice = s2.nextLine();
                //displayDealerCovered(Dealer, Player);
              }
            }
          }
          Choice = "Q";
        }
        else if(Choice.equalsIgnoreCase("N"))
        {
          System.out.println("You have not split your first hand.");
          Choice = "Q";
          //displayDealerCovered(Dealer, Player);
        }
        else
        {
          System.out.println("Invalid Option!");
          Choice = "";
          Choice = s2.nextLine();
          //displayDealerCovered(Dealer, Player);
        }
      }
    }
  }
  
  /**
   * Player's turn
   * @param GameDeck
   * @param Player
   * @param handCounter
   */
  public void PlayerTurn(GameDeck GameDeck, Player Player, int handCounter)
  {
    Scanner scan = new Scanner(System.in);
    String userin = "";
    int InitialBet = Player.getBet(1 - 1);
    System.out.println("");
    //Display the available options of the hand that the player can make.
    while(Player.canStand(handCounter - 1))
    {
      System.out.print(Player.getCards());
      if(!Player.handValue(handCounter - 1).equals("BLACKJACK") 
         && !Player.handValue(handCounter - 1).equals("BUSTED") 
         && Player.sum(handCounter - 1) != 21) 
      {
        System.out.println("");
        System.out.print("Please enter your Action for Hand " + handCounter + ": ");
        if(Player.canHit(handCounter - 1))
        {
          System.out.print("Hit(H) ");
          if(Player.canStand(handCounter - 1))
          {
            System.out.print("Stand(S) ");
            if(Player.canDoubleDown(handCounter - 1))
            {
              System.out.print("DoubleDown(D) ");
            }
          }
        }
        userin = "";
        if(Player.handValue(handCounter - 1).equals("BUSTED"))
        {
          userin = "s";
        }
        else
        {
          userin = scan.nextLine();
        }
        //hit
        if(userin.equalsIgnoreCase("hit") || userin.equalsIgnoreCase("h"))
        {
          if(Player.canHit(handCounter - 1))
          {
            Player.play(GameDeck, handCounter - 1, Action.HIT);
            System.out.println("You chose to Hit.");
          }
          else
          {
            System.out.println("You can no longer Hit on hand " + handCounter);
          }
        }
        
        //stand
        else if(userin.equalsIgnoreCase("stand") || userin.equalsIgnoreCase("s"))
        {
          if(Player.canStand(handCounter - 1))
          {
            Player.play(GameDeck, handCounter - 1, Action.STAND);
            System.out.println("You chose to Stand.");
          }
          else
          {
            System.out.println("You can no longer Stand on hand " + handCounter);
          }
        }
        
        //double down
        else if(userin.equalsIgnoreCase("doubledown") || userin.equalsIgnoreCase("d"))
        {
          if(Player.canDoubleDown(handCounter - 1))
          {
            
            //checks if the player has enough money to doubledown
            if(Player.canBet(InitialBet))
            {
              Player.play(GameDeck, handCounter - 1, Action.DOUBLE_DOWN);
              System.out.println("You chose to DoubleDown.");
              // BRANDEN: Temporarily removed this because the betting for doubling down
              // is already handled within the Seat class
              /*
              Player.setBet(handCounter - 1, 2 * InitialBet);
              */
            }
            else
            {
              System.out.println("You do not have enough cash.");
            }
          }
          else
          {
            System.out.println("You can no longer DoubleDown on hand " + handCounter);
          }
        }
      }
      else 
      {
        Player.play(GameDeck, handCounter - 1, Action.STAND);
        if(Player.handValue(handCounter - 1).equals("BLACKJACK"))
        {
          System.out.println("You have BLACKJACK!");
        }
        else if(Player.handValue(handCounter - 1).equals("BUSTED"))
        {
          System.out.println("Hand " + handCounter + " BUSTED!");
        }
      }
      System.out.println("");
    }
  }
  
  /**
   * The Dealer's turn
   * @param Dealer
   * @param GameDeck
   */
  public void DealerTurn(Dealer Dealer,  GameDeck GameDeck)
  {
    boolean done;
    Action Action;
    
    done = false;
    Action = null;
    
    // Show all cards that the dealer has
    Dealer.setShowCards(true);
    System.out.println("Dealer's Hand: ");
    System.out.print(Dealer.getCards());
    System.out.print("     Enter anything to continue.");
    spacer = s.nextLine();
    while(!done){
      
      //loop until the dealer stands
      while(Action != Action.STAND)
      {
        Action = Dealer.getMove(GameDeck, 1 - 1, Dealer.hands[0][1]);
        Dealer.play(GameDeck, 1 - 1, Action);
        System.out.println("Dealer " + Action + "s");
        if(Action != Action.STAND)
        {
                  System.out.print(Dealer.getCards());
        System.out.print("     Enter anything to continue.");
        spacer = s.nextLine();
        }
      }
      done = true;
    }
  }
  
  /**
   * The Payout part at the end of each round
   * @param Dealer
   * @param Player
   */
  public void Payout(Dealer Dealer, Player Player)
  {
    for(int handCounter = 1; handCounter < 5; handCounter++)
    {
      if(Player.hands[handCounter - 1][0] != null) 
      {
        if(!Player.handValue(0).equals("BLACKJACK"))
        { 
          if(((Player.sum(handCounter - 1) > Dealer.sum(0)) && 
             (Player.sum(handCounter - 1) <= 21)) ||
             ((Player.sum(handCounter - 1) <= 21) && ((Dealer.sum(0) > 21))))
          {
            System.out.print("Hand " + handCounter + " won! You won $" + (2 * Player.getBet(handCounter - 1)));
            Player.setMoney(Player.getMoney() + 2 * Player.getBet(handCounter - 1));
          }
          else if (((Dealer.sum(0) > Player.sum(handCounter - 1)) && 
                    (Dealer.sum(0) <= 21)) ||
                   ((Dealer.sum(0) <= 21) && ((Player.sum(handCounter - 1) > 21))))
          {
            System.out.print("Hand " + handCounter + " lost! You lost $" + Player.getBet(handCounter - 1));
            Player.setMoney(Player.getMoney() - Player.getBet(handCounter - 1));
          }
          else
          {
            System.out.print("Hand " + handCounter + " tied!");
          }
        }
        //Payout for player BLACKJACK is 3:2
        //if Dealer also has BLACKJACK, then it is a tie
        else
        {
          if(Dealer.handValue(0).equals("BLACKJACK")) {
            System.out.println("Dealer Also has BLACKJACK!");
            System.out.println("Hand " + handCounter + " tied!");
          } else {
            System.out.println("Hand " + handCounter + " won! You won $" + (3 * Player.getBet(handCounter - 1) / 2));
            Player.setMoney(Player.getMoney() + (3 * Player.getBet(handCounter - 1) / 2));
          }
        } 
        System.out.print("     Enter anything to continue.");
        spacer = s.nextLine();
      }
    }
  }
  
  /**
   * Clears all bets, hands, and hand status of the Player and Dealer
   * @param Dealer
   * @param Player
   */
  public void ClearTable(Dealer Dealer, Player Player)
  {
    Player.clear();
    Dealer.clear();
  }
  
}






















